package pl.egraveyard.dao;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.apache.commons.lang.Validate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;

/**
 * Domyslna implementacja interfejsu {@link AbstractSlDaoSupport}
 * @author gunos
 *
 * @param <T> kla obiektu slownika
 */
public class AbstractSlDaoSupportImpl<T> implements AbstractSlDaoSupport<T> {
	private Class<T> entityClass;
	private SessionFactory sessionFactory;
	
	
	/**
	 * Domyslny konstruktor
	 */
	@SuppressWarnings("unchecked")
	public AbstractSlDaoSupportImpl(){
		this.entityClass = (Class<T>) ((ParameterizedType) this.getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
	}
	
	/**
	 * @param sessionFactory the sessionFactory to set
	 */
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}
	
	/**
	 * Pobiera aktualna sesje
	 * @return aktualna sesje
	 */
	public Session getCurrentSession(){
		return sessionFactory.getCurrentSession();
	}

	/**
	 * {@inheritDoc}
	 */
	@SuppressWarnings("unchecked")
	@Override
	public T read(Integer id) {
		Validate.notNull(id);
		T obj = (T) getCurrentSession().createCriteria(entityClass)
				.add(Restrictions.eq("id", id)).uniqueResult();
		getCurrentSession().evict(obj);
		return obj;
	}

	/**
	 * {@inheritDoc}
	 */
	@SuppressWarnings("unchecked")
	@Override
	public T read(String code) {
		Validate.notEmpty(code);
		T obj = (T) getCurrentSession().createCriteria(entityClass)
				.add(Restrictions.eq("kod", code)).uniqueResult();
		getCurrentSession().evict(obj);
		return obj;
	}

	/**
	 * {@inheritDoc}
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<T> readAll() {
		List<T> objs = getCurrentSession().createCriteria(entityClass).list();
		for (T obj : objs) {
			getCurrentSession().evict(obj);
		}
		return objs;
	}

}
